package com.rem.se.test3;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * @author Rem
 * @date 2023-05-04
 */
public class LazyIterator<T> implements Iterable<T> {
    public static void main(String[] args) {
        ValueLoader<Integer> valueLoader = new ValueLoader<Integer>() {
            @Override
            public List<Integer> load(long offset, int limit) {
                // 生成10个随机数，值域为 [1, 100]
                List<Integer> list = new ArrayList<>();
                for (int i = 0; i < limit; i++) {
                    list.add((int) (1 + Math.random() * 100));
                }
                return list;
            }
        };

        LazyIterator<Integer> lazyItr = new LazyIterator<>(valueLoader);
        for (Integer integer : lazyItr) {
            System.out.println(integer);
            try {
                Thread.sleep(1000);   // 模拟每秒钟输出一个数的情况
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private final ValueLoader<T> valueLoader;
    /**
     * 记录当前已经获取的数据的位置
     */
    private long offset = 0L;
    /**
     * 用于存放当前获取的数据缓存
     */
    private List<T> buffer = null;

    public LazyIterator(ValueLoader<T> valueLoader) {
        this.valueLoader = valueLoader;
    }

    @Override
    public Iterator<T> iterator() {
        return new Itr();
    }

    private class Itr implements Iterator<T> {
        // 缓存中当前遍历的位置
        private int index = 0;
        // 标记是否已经遍历到结尾
        private boolean reachEnd = false;

        @Override
        public boolean hasNext() {
            // 当缓存为空或者已全部遍历，需要继续获取新数据
            if (buffer == null || index == buffer.size()) {
                // 每次获取10条数据
                buffer = valueLoader.load(offset, 10);
                // 如果获取的新数据为空，则认为已经遍历结束
                if (buffer == null || buffer.isEmpty()) {
                    reachEnd = true;
                } else {
                    // 更新已经获取的数据的位置
                    offset += buffer.size();
                    // 遍历位置归零
                    index = 0;
                }
            }
            return !reachEnd;
        }

        @Override
        public T next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            T next = buffer.get(index);
            index++;
            return next;
        }
    }
}

/*interface ValueLoader<T> {

 *//**
 * 加载
 *
 * @param offset
 * @param limit
 * @return
 *//*
    List<T> load(long offset, int limit);
}*/
